/**
 * 
 * Neo Touchable RIA Framework - A Web RIA Javascript Framework
 * 
 * Copyright (c) 2012
 * Dual licensed under the MIT or GPL v2 licenses.
 * 
 * @author  CuTe_CuBe
 * @version $Id: location.js 8 2012-03-11 14:16:41Z cc.hgfeng@gmail.com $
 */

/**
 * OTR.Location 提供监听|管理用户访问地址的方法
 * 
 */
OTR.Location = {

    /**
     * 监听回调函数列表
     * 
     * @private
     * @type Array
     */
    _callbacks: [],

    /**
     * 当前hash
     * 
     * @private
     * @type string
     */
    _hash: null, 
    
    /**
     * QueryString 起始表示字符
     * 
     * @private
     * @type string
     */
    _queryMark: '~',

    /**
     * 注册地址变更事件监听回调函数
     * 
     * @param   Function func
     * @return  OTR.Location
     */
    addChangeListener: function(func) {
        if (typeof func == 'function') {
            this._callbacks.push(func);
        }

        return this;
    },

    /**
     * 移除 指定的|所有 注册地址变更事件监听事件回调函数
     * 
     * @param   Function func
     * @return  OTR.Location
     */
    removeChangeListener: function(func) {
        if (undefined == func) {
            for (var i = 0, c = this._callbacks.length; i < c; i++) {
                delete this._callbacks[i];
            }
            
            this._callbacks = [];
            return this;
        }

        if (typeof func == 'function') {
            for (var i = 0, c = this._callbacks.length; i < c; i++) {
                if (func == this._callbacks[i]) {
                    delete this._callbacks[i];
                }
            }
        }
        
        return this;
    },

    /**
     * 触发hashchange事件绑定
     */
    fireChangeEvent: function(){
        var cb = this._callback,
            l  = cb.length,
            U  = OTR.Util;
        
        for (var i = 0; i < l; i++) {
            if (U.isFunction(cb[i])) {
                cb[i](location.hash);
            }
        }
    },

    /**
     * 构建QueryString
     * 
     * @param object obj
     * @return string
     */
    buildQueryString: function(obj) {
        if (!OTR.Util.isObject(obj)) {
            return '';
        }
        
        var q = [];
        for (var k in obj) {
            if (OTR.Util.isArray(obj[k])) {
                for (var i = 0, c = obj[k].length; i < c; i++) {
                    q.push(k + '[]=' + obj[k][i]);
                }
            } else {
                q.push(k + '=' + encodeURIComponent(obj[k]));
            }
        }
        
        return q.join('&');
    },

    /**
     * 刷新页面
     * 参数为刷新级别，默认为1
     * 0.采用跳转方式，仅刷新无缓存的数据
     * 1.普通刷新(F5)
     * 2.强制刷新(Ctrl + F5)
     * 
     * @param int level
     */
    reload: function(level) {
        if (undefined === level) {
            level = 1;
        }
        
        if (level == 1) {
            location.reload();
        } else if (level == 0) {
            history.go(0);
        } else {
            location.reload(true);
        }
    },

    /**
     * 跳转到指定URL
     * 
     * @param url
     */
    go: function(url) {
        location.assign(url);
    },

    /**
     * 获取 | 设置location hash
     * 
     * @param string  str
     * @param boolean fire
     * @return mixed
     */
    hash: function(str, fire) {
        if (undefined !== str && OTR.Util.isString(str)) {
            // 通过程序调用，更新本地缓存的hash，避免触发事件
            if (undefined !== file && file) {
                this._hash = str;
            }
            location.hash = str;
            return ;
        }
        
        return location.hash;
    },

    /**
     * 检查hash是否被改变
     * 
     * @return boolean
     */
    isChanged: function() {
        return this._hash != location.hash;
    },

    /**
     * 初始化绑定hashchange事件
     * 
     * @return void
     */
    initHashChange: function() {
        if (window.onhashchange) {
            window.onhashchange = function(){
                var L = OTR.Location;
                if (L.isChanged()) {
                    L._hash = location.hash;
                    L.fireChangeEvent();
                }
            };
        // 不支持的浏览器  :-(
        } else {
            this._interval = setInterval(function(){
                var L = OTR.Location;
                if (L.isChanged()) {
                    L.fireChangeEvent();
                }
            }, 100);
        }
    },

    /**
     * 取消hashchange事件监听
     * 
     * @return void
     */
    detachHashChange: function() {
        if (window.onhashchange) {
            window.onhashchange = null;
        }

        if (this._interval) {
            clearInterval(this._interval);
            this._interval = null;
        }
    }
};